/*
 * $Id: ReportHandler.java 657 2007-06-29 07:07:01Z jacek.kolezynski $
 */
package logmatcher.report;

import logmatcher.report.ReportEvent.Type;

import logmatcher.utils.Config;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;


/**
*  Class of report from the suite.
 */
public class ReportHandler {
    //~ Static fields/initializers -------------------------------------------------------------------------------------

    /** Class logger. */
    private static final Log reportLogger = LogFactory.getLog(ReportHandler.class);

    /** Line separator. */
    private static String ENDL = System.getProperty("line.separator");

    /** Success string. */
    private static String SUCCESS = "SUCCESS";

    /** Failure string. */
    private static String FAILURE = "FAILURE";
    
    /** Test started string. */
    private static String TEST_STARTED = "TEST_STARTED";
    
    /** Test ended string. */
    private static String TEST_ENDED = "TEST_ENDED";

    /** End of test log message. */
    static final String END_OF_TEST = "--- END OF REPORT ---";
    
    private int numberOfTests;

    //~ Instance fields ------------------------------------------------------------------------------------------------

    /** TODO: DOCUMENT ME! */
/** TODO: DOCUMENT ME! */
/** Events from test cases. */
    List<ReportEvent> events = Collections.synchronizedList(new ArrayList<ReportEvent>());

    /** The name of the suite. */
    private String suiteName;

    //~ Constructors ---------------------------------------------------------------------------------------------------

/**
     *  Creates a new Report object.
    *
     *  @param suiteName the name of the suite
    */
    public ReportHandler(String suiteName) {
        this.suiteName = suiteName;
    }

    //~ Methods --------------------------------------------------------------------------------------------------------

    /**
    *  Clear all ReportEvents received so far.
    */
    public void clear() {
        events.clear();
    }


    /**
    *  Returns the suite name.
    *
    *  @return suite name
    */
    public String getSuiteName() {
        return suiteName;
    }


    /**
    *  Prints report from the suite. Automatically clears printed events.
    */
    public void printReport() {      
        // set number of tasks, be sure it's a valid value       
        reportLogger.info("-------------------- Test suite report for: "+suiteName+" --------------------");
               
        // store next part of the log in the buffer and print the data at the end
        StringBuilder builder = new StringBuilder();
        builder.append("-------------------- Details --------------------").append(ENDL);
        int successfulTasks = 0;
        int numberOfTasks = 2;
        int passedTests = 0;
        int i = 0;
        for (ReportEvent event : events) {
        	Type type = event.getType();
        	
            builder.append(getResultText(type));
            builder.append(" : ");

            String message = event.getMessage();

            if ((message != null) && (message.equals("") == false)) {
                builder.append(message);
            }
            
        	if(type == Type.PASSED){
        		successfulTasks++;
        	}else if(type == Type.TEST_ENDED){
        		numberOfTasks = ((Integer)event.getInfo()).intValue();
        		if(successfulTasks == numberOfTasks )
        			passedTests++;
        		successfulTasks = 0;
        		builder.append(ENDL+"---"+ENDL);
        	}

            builder.append(ENDL);
            i++;            
        }        
        
        reportLogger.info("-------------------- Summary --------------------");
        reportLogger.info("Number of tests executed: "+numberOfTests);
        
        reportLogger.info("Number of tests passed: "+passedTests);
        reportLogger.info("Execution result: "+ (passedTests==numberOfTests?SUCCESS : FAILURE));

                
        builder.append("-------------------- End of test suite report for: ");
        builder.append(suiteName).append(" --------------------");
        // write to logger data stored in the buffer
        reportLogger.info(builder.toString());
        reportLogger.info(END_OF_TEST);
        
        // remove all events from the list
        clear();
    }


    /**
    *  Receives a single event.
    *
    *  @param event the event
    */
    public void receiveEvent(ReportEvent event) {
        events.add(event);
        if(event.getType() == ReportEvent.Type.TEST_STARTED){
        	numberOfTests ++;
        }
        	
    }


    /**
    *  Sets the suite name.
    *
    *  @param suiteName the suite name
    */
    public void setSuiteName(String suiteName) {
        this.suiteName = suiteName;
    }


    /**
    *  Returns result text.
    *
    *  @param r the result text
    *
    *  @return TODO: DOCUMENT ME!
    */
    private final String getResultText(Type r) {
        if (r == Type.PASSED) {
            return SUCCESS;
        } else if (r == Type.FAILED){
            return FAILURE;
        } else if (r == Type.TEST_STARTED){
        	return TEST_STARTED;
        } else
        	return TEST_ENDED;
    }
}
